package com.zyx.order.server.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zyx.order.server.common.enums.OrderStatus;
import com.zyx.order.server.model.dto.OrderMessageDTO;
import com.zyx.order.server.model.po.OrderDetailPO;
import com.zyx.order.server.model.vo.OrderCreateVO;
import com.zyx.order.server.service.IOrderDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

@Slf4j
@Service
public class OrderService {

    @Autowired
    private IOrderDetailService orderDetailService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    public void createOrder(OrderCreateVO orderCreateVO) throws IOException, TimeoutException, InterruptedException {
        log.info("createOrder:orderCreateVO:{}", orderCreateVO);
        OrderDetailPO orderPO = new OrderDetailPO();
        orderPO.setAddress(orderCreateVO.getAddress());
        orderPO.setAccountId(orderCreateVO.getAccountId());
        orderPO.setProductId(orderCreateVO.getProductId());
        orderPO.setStatus(OrderStatus.ORDER_CREATING);
        orderPO.setDate(new Date());
        orderDetailService.save(orderPO);

        OrderMessageDTO orderMessageDTO = new OrderMessageDTO();
        orderMessageDTO.setOrderId(orderPO.getId());
        orderMessageDTO.setProductId(orderPO.getProductId());
        orderMessageDTO.setAccountId(orderCreateVO.getAccountId());

        String messageToSend = objectMapper.writeValueAsString(orderMessageDTO);

        // 使用 rabbitTemplate 发送消息
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setExpiration("15000");
        Message message = new Message(messageToSend.getBytes(), messageProperties);

        // correlationData可以指定id, 便于消息返回时的后续处理
        CorrelationData correlationData = new CorrelationData();
        correlationData.setId(orderPO.getId().toString());
        // send方法可以设置消息的属性
        rabbitTemplate.send("exchange.order.restaurant", "key.restaurant", message, correlationData);

        // convertAndSend无法直接设置消息的属性
        // rabbitTemplate.convertAndSend("exchange.order.restaurant", "key.restaurant", messageToSend);

        log.info("message sent");
        TimeUnit.MILLISECONDS.sleep(800);
    }

    /* ==================================== 原生RabbitMQ接口发送消息 ====================================*/
    // import com.rabbitmq.client.*;
    // public void createOrder(OrderCreateVO orderCreateVO) throws IOException, TimeoutException, InterruptedException {
    //     log.info("createOrder:orderCreateVO:{}", orderCreateVO);
    //     OrderDetailPO orderPO = new OrderDetailPO();
    //     orderPO.setAddress(orderCreateVO.getAddress());
    //     orderPO.setAccountId(orderCreateVO.getAccountId());
    //     orderPO.setProductId(orderCreateVO.getProductId());
    //     orderPO.setStatus(OrderStatus.ORDER_CREATING);
    //     orderPO.setDate(new Date());
    //     orderDetailService.save(orderPO);
    //
    //     OrderMessageDTO orderMessageDTO = new OrderMessageDTO();
    //     orderMessageDTO.setOrderId(orderPO.getId());
    //     orderMessageDTO.setProductId(orderPO.getProductId());
    //     orderMessageDTO.setAccountId(orderCreateVO.getAccountId());
    //
    //     ConnectionFactory connectionFactory = new ConnectionFactory();
    //     connectionFactory.setHost("81.68.117.201");
    //
    //     try (Connection connection = connectionFactory.newConnection();
    //          Channel channel = connection.createChannel()) {
    //         channel.confirmSelect();
    //         ConfirmListener confirmListener = new ConfirmListener() {
    //             public void handleAck(long deliveryTag, boolean multiple) throws IOException {
    //                 log.info("==========>>>>>>>>>> Ack, deliveryTag: {}, multiple: {}", deliveryTag, multiple);
    //             }
    //
    //             public void handleNack(long deliveryTag, boolean multiple) throws IOException {
    //                 log.info("==========>>>>>>>>>> Nack, deliveryTag: {}, multiple: {}", deliveryTag, multiple);
    //             }
    //         };
    //         // 异步确认
    //         channel.addConfirmListener(confirmListener);
    //         String messageToSend = objectMapper.writeValueAsString(orderMessageDTO);
    //
    //         // 演示多条确认
    //         // for (int i = 0; i < 50; i++) {
    //         //     channel.basicPublish(
    //         //             "exchange.order.restaurant", "key.restaurant", null, messageToSend.getBytes());
    //         //     log.info("==========>>>>>>>>>> {}", "message sent");
    //         // }
    //
    //         // 设置TTL, 单位为ms
    //         AMQP.BasicProperties basicProperties = new AMQP.BasicProperties().builder().expiration("15000").build();
    //         // channel.basicPublish(
    //         //         "exchange.order.restaurant", "key.restaurant", basicProperties, messageToSend.getBytes());
    //
    //         channel.basicPublish(
    //                 "exchange.order.restaurant", "key.restaurant", null, messageToSend.getBytes());
    //         log.info("==========>>>>>>>>>> {}", "message sent");
    //
    //         // 同步确认
    //         // if (channel.waitForConfirms()) {
    //         //     log.info("==========>>>>>>>>>> {}", "Rabbit confirm success");
    //         // } else {
    //         //     log.info("==========>>>>>>>>>> {}", "Rabbit confirm failed");
    //         // }
    //
    //         TimeUnit.MILLISECONDS.sleep(1000);
    //     }
    // }

}
